07. Navigation Goal Node
Reaching Multiple Goals
Earlier, you tested your robot capabilities in reaching multiple goals by manually commanding it to travel with the 2D NAV Goal arrow in rviz. Now, you will write a node that will communicate with the ROS navigation stack and autonomously send successive goals for your robot to reach. As mentioned earlier, the ROS navigation stack creates a path for your robot based on Dijkstra's algorithm, a variant of the Uniform Cost Search algorithm, while avoiding obstacles on its path.
There is an official ROS tutorial that teaches you how to send a single goal position and orientation to the navigation stack. You are already familiar with this code from the Localization project where you used it to send your robot to a pre-defined goal. Check out the tutorial and go through its documentation.
Here’s the C++ code of this node which sends a single goal for the robot to reach. I included some extra comments to help you understand it:
#include <ros/ros.h>
#include <move_base_msgs/MoveBaseAction.h>
#include <actionlib/client/simple_action_client.h>
// Define a client for to send goal requests to the move_base server through a SimpleActionClient
typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient;
int main(int argc, char** argv){
// Initialize the simple_navigation_goals node
ros::init(argc, argv, "simple_navigation_goals");
//tell the action client that we want to spin a thread by default
MoveBaseClient ac("move_base", true);
// Wait 5 sec for move_base action server to come up
while(!ac.waitForServer(ros::Duration(5.0))){
ROS_INFO("Waiting for the move_base action server to come up");
}
move_base_msgs::MoveBaseGoal goal;
// set up the frame parameters
goal.target_pose.header.frame_id = "base_link";
goal.target_pose.header.stamp = ros::Time::now();
// Define a position and orientation for the robot to reach
goal.target_pose.pose.position.x = 1.0;
goal.target_pose.pose.orientation.w = 1.0;
// Send the goal position and orientation for the robot to reach
ROS_INFO("Sending goal");
ac.sendGoal(goal);
// Wait an infinite time for the results
ac.waitForResult();
// Check if the robot reached its goal
if(ac.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
ROS_INFO("Hooray, the base moved 1 meter forward");
else
ROS_INFO("The base failed to move forward 1 meter for some reason");
return 0;
}
Reaching Multiple Goals
Customize the code
You will need to modify this code and edit its node name to
pick_objects
. Then, edit the
frame_id
to
map
, since your fixed frame is the map and not base_link. After that, you will need to modify the code and include an extra goal position and orientation for your robot to reach.
The first goal should be your desired pickup goal and the second goal should be your desired drop off goal. The robot has to travel to the desired pickup zone, display a message that it reached its destination, wait 5 seconds, travel to the desired drop off zone, and display a message that it reached the drop off zone.
Reaching Multiple Goals
Task Description:
Follow these instructions to autonomously command the robot to travel to both desired pickup and drop off zones:
Task Feedback:
Nicely done!